﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace RouterControlTest
{
	/// <summary>
	/// Summary description for IntelUpnpStackTest
	/// </summary>
	[TestClass]
	public class IntelUpnpStackTest
	{
		public IntelUpnpStackTest()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		private TestContext testContextInstance;

		/// <summary>
		///Gets or sets the test context which provides
		///information about and functionality for the current test run.
		///</summary>
		public TestContext TestContext
		{
			get
			{
				return testContextInstance;
			}
			set
			{
				testContextInstance = value;
			}
		}

		#region Additional test attributes
		//
		// You can use the following additional attributes as you write your tests:
		//
		// Use ClassInitialize to run code before running the first test in the class
		// [ClassInitialize()]
		// public static void MyClassInitialize(TestContext testContext) { }
		//
		// Use ClassCleanup to run code after all tests in a class have run
		// [ClassCleanup()]
		// public static void MyClassCleanup() { }
		//
		// Use TestInitialize to run code before running each test 
		// [TestInitialize()]
		// public void MyTestInitialize() { }
		//
		// Use TestCleanup to run code after each test has run
		// [TestCleanup()]
		// public void MyTestCleanup() { }
		//
		#endregion

		[TestMethod]
		public void FindDevices()
		{
			var cp = new Intel.UPNP.UPnPControlPoint();

			cp.OnSearch += new Intel.UPNP.UPnPControlPoint.SearchHandler(cp_OnSearch);

			cp.FindDeviceAsync(RouterControl.IO.RootDeviceTypeIds.InternetGatewayDeviceType);

			System.Threading.Thread.Sleep(2000);
		}

        [TestMethod]
        public void FindDevicesDsl()
        {
            var cp = new Intel.UPNP.UPnPControlPoint();

            cp.OnSearch += new Intel.UPNP.UPnPControlPoint.SearchHandler(cp_OnSearch);

            cp.FindDeviceAsync(RouterControl.IO.RootDeviceTypeIds.InternetGatewayDslDeviceType);

            System.Threading.Thread.Sleep(2000);
        }

		private void cp_OnSearch(System.Net.IPEndPoint ResponseFromEndPoint, System.Net.IPEndPoint ResponseReceivedOnEndPoint, Uri DescriptionLocation, string USN, string SearchTarget, int MaxAge)
		{
			Console.WriteLine("On Search:");
			Console.WriteLine(USN);
			Console.WriteLine(DescriptionLocation.ToString());

			// create device
			var df = new Intel.UPNP.UPnPDeviceFactory();

			df.OnDevice += new Intel.UPNP.UPnPDeviceFactory.UPnPDeviceHandler(df_OnDevice);
			df.OnFailed += new Intel.UPNP.UPnPDeviceFactory.UPnPDeviceFailedHandler(df_OnFailed);

			df.CreateDevice(DescriptionLocation, 5);

			System.Threading.Thread.Sleep(2000);
		}

		private void df_OnFailed(Intel.UPNP.UPnPDeviceFactory sender, Uri URL, Exception e)
		{
			Console.WriteLine("On Failed:");
			Console.WriteLine(e.Message);
			Console.WriteLine(URL.ToString());
		}

		private void df_OnDevice(Intel.UPNP.UPnPDeviceFactory sender, Intel.UPNP.UPnPDevice device, Uri URL)
		{
			Console.WriteLine("On Device:");
			Console.WriteLine(device.FriendlyName);
			Console.WriteLine(URL.ToString());

			DumpDevice(device);
		}

		private void DumpDevice(Intel.UPNP.UPnPDevice device)
		{
			Console.WriteLine("Dump Device:");
			Console.WriteLine(device.FriendlyName);
			Console.WriteLine(device.DeviceURN);
			Console.WriteLine(device.LocationURL);

			// dump services
			foreach (var d in device.Services)
			{
				DumpService(d);
			}

			// dump children
			foreach (var d in device.EmbeddedDevices)
			{
				DumpDevice(d);
			}
		}

		private void DumpService(Intel.UPNP.UPnPService service)
		{
			Console.WriteLine("Dump Service:");
			Console.WriteLine(service.ServiceID);
			Console.WriteLine(service.ServiceURN);

			// dump variables
			foreach (var v in service.GetStateVariables())
			{
				v.OnModified += new Intel.UPNP.UPnPStateVariable.ModifiedHandler(v_OnModified);

				Console.Write(v.Name);
				Console.Write(" : ");
				Console.Write(v.ValueType);
				Console.Write(" = ");
				Console.WriteLine(service.GetStateVariable(v.Name));
			}

			// dump actions
			foreach (var d in service.GetActions())
			{
				Console.Write(d.Name);
				Console.Write(" (");

				foreach (var a in d.ArgumentList)
				{
					Console.Write(a.RelatedStateVar.ValueType);
					Console.Write(" ");
					Console.Write(a.Name);
					Console.Write(", ");
				}

				Console.WriteLine(")");
			}
		}

		private void v_OnModified(Intel.UPNP.UPnPStateVariable v, object NewValue)
		{
			Console.WriteLine("On Modified");
			Console.Write(v.Name);
			Console.Write(" : ");
			Console.Write(v.ValueType);
			Console.Write(" = ");
			Console.WriteLine(v.Value);
		}
	}
}
